/*
* 绘制路线时
* 步骤：初始化(init) > 开始绘制（drawBezier）
*/
import MyWriting from './mywriting.esm'
export default {
  pointSpeedNum: 1, // 控制播放笔迹数目
  timer: null, // 绘制笔迹的动画定时器
  // 初始化
  init ({
    canvas, // 必填
    strokeStyle = '#333333', // 非必填
    lineJoin = 'round', // 非必填
    lineCap = 'round' // 非必填
  }) {
    let ctx = canvas.getContext('2d')

    // 设置线条颜色
    ctx.strokeStyle = strokeStyle
    ctx.lineJoin = lineJoin
    ctx.lineCap = lineCap

    return ctx // 返回画布的上下文
  },
  // 延迟操作
  delay (timeout = 50) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
      }, timeout)
    })
  },
  // 清除定时器
  clearTimeOut () {
    if (this.timer) {
      window.clearTimeout(this.timer)
      this.timer = null
    }
  },
  getImage (url) {
    return new Promise((resolve, reject) => {
      let image = new window.Image()
      // 引用外部图片，需设置 crossOrigin 属性，否则 toDataURL 调用异常
      image.setAttribute('crossOrigin', 'anonymous')
      image.src = url
      image.onload = function () {
        resolve(image)
      }
      image.onerror = function () {
        reject(new Error('图片资源加载失败'))
      }
    })
  },
  // 绘制贝塞尔曲线
  drawBezier ({
    ctx, // 必 填 - init返回的上下文
    beginPoint, // 必 填
    controlPoint, // 必 填
    endPoint, // 必 填
    strokeStyle, // 非必填 -- 设置颜色
    lineWidth = 2, // 线条宽度
    ratio = 1
  }) {
    ctx.beginPath()
    ctx.setLineDash([])
    ctx.moveTo(beginPoint.x * ratio, beginPoint.y * ratio)
    ctx.quadraticCurveTo(controlPoint.x * ratio, controlPoint.y * ratio, endPoint.x * ratio, endPoint.y * ratio)
    if (strokeStyle) {
      ctx.strokeStyle = strokeStyle
    }
    ctx.lineWidth = lineWidth * ratio
    ctx.stroke()
    ctx.closePath()
  },
  isPlayPoint (pointMaxNum) {
    return new Promise((resolve, reject) => {
      if (this.pointSpeedNum <= pointMaxNum) {
        this.pointSpeedNum++
        resolve()
      } else {
        this.pointSpeedNum = 1
        this.timer = setTimeout(() => {
          resolve()
        }, 10)
      }
    })
  },
  // 绘制贝塞尔曲线 -- 添加动画(使用async函数)
  async drawBezierAni ({
    ctx, // 必 填 - init返回的上下文
    radio = 1,
    beginPoint, // 必 填
    controlPoint, // 必 填
    endPoint, // 必 填
    strokeStyle, // 非必填 -- 设置颜色
    pointMaxNum = 2, // 每10ms播放点数
    width, // 橡皮擦的宽度
    type // 类型 pen: 画笔 eraser: 橡皮擦
  }) {
    await this.isPlayPoint(pointMaxNum)
    ctx.beginPath()
    ctx.setLineDash([])
    ctx.moveTo(beginPoint.x * radio, beginPoint.y * radio)
    ctx.quadraticCurveTo(controlPoint.x * radio, controlPoint.y * radio, endPoint.x * radio, endPoint.y * radio)
    if (strokeStyle) {
      ctx.strokeStyle = strokeStyle
    }
    ctx.lineWidth = (type === 'pen' ? 2 : width)
    if (type === 'eraser') { // 设置透明色
      ctx.globalCompositeOperation = 'destination-out'
    } else {
      ctx.globalCompositeOperation = 'destination-over'
    }
    ctx.stroke()
    ctx.closePath()
  },
  /**
   * 裁剪canvas的部分image数据
   * @type {Number}
   */
  getPartOfImage () {
    // 要裁剪的位置信息
    let startX = 0; let startY = 0; let endX = 80; let endY = 80
    let canvas = document.querySelector('canvas')
    let ctx = canvas.getContext('2d')

    // 获取具体位置的图片信息
    let cutImageData = ctx.getImageData(startX, startY, endX, endY)

    // 创建新的canvas对象
    let cutCanvas = document.createElement('canvas')
    cutCanvas.height = endY - startY
    cutCanvas.width = endX - startX
    let cutCtx = cutCanvas.getContext('2d')

    // 将裁减信息放到新的canvas对象中
    cutCtx.putImageData(cutImageData, 0, 0)

    // 转成iamgeData
    let imageData = cutCanvas.toDataURL()
    console.log(imageData)
  },
  /*
  * 集成绘制canvas的组件
  */
  // 初始化组件的画布
  initCoreWriting ({
    className,
    ink = { // 画笔墨水设置
      color: '#ffffff',
      penWidth: 0.2 * 5
    },
    eraser = { // 橡皮擦 -- 圆形擦除
      color: 'transparent',
      strokeColor: '#000000',
      penWidth: 15,
      lineWidth: 2,
      pointer: false
    },
    type = 'pen' // select: 选择  pen:画笔 wiper: 橡皮
  }) {
    let writingArr = []
    document.querySelectorAll(className).forEach((element) => {
      if (MyWriting) {
        let mw = MyWriting.register(
          element,
          {
            render: 'canvas'
          },
          {
            // 画笔
            ink,
            // 橡皮擦
            eraser
          },
          {
            type
          }
        )
        writingArr.push(mw)
      }
    })
    return writingArr
  },
  /* 画布尺寸变化时 */
  resize ({ className }) {
    document.querySelectorAll(className).forEach((element) => {
      if (element.editor) {
        element.editor.resize()
      }
    })
  },
  // 获取所有组件画布的数据
  getCoreWritingData ({
    className
  }) {
    let arr = []
    document.querySelectorAll(className).forEach((element) => {
      if (element.editor && element.editor.model && element.editor.model.rawStrokes) {
        arr.push(element.editor.model.rawStrokes)
      } else {
        arr.push('error')
      }
    })
    return arr
  },
  getCoreWritingDataSingle ({
    className
  }) {
    let arr = []
    let element = document.querySelector(className)
    if (element.editor) {
      arr = element.editor.model.rawStrokes
    }
    return arr
  },
  // 绘制已有的笔迹数据
  coreWritingRedraw ({
    className,
    data
  }) {
    document.querySelectorAll(className).forEach((element, index) => {
      if (element.editor) {
        element.editor.reDraw(data[index])
      }
    })
  },
  // 绘制已有的笔迹数据（单个绘制）
  coreWritingRedrawSingle ({
    className,
    data
  }) {
    const element = document.querySelector(className)
    element.editor.reDraw(data)
  },
  // 设置绘制参数
  setPenStyle ({
    className,
    type = 'pen', // select:选中状态 pen:钢笔 eraser:橡皮檫
    ink = {
      color: '#FF2121',
      penWidth: 0.2 * 3
    },
    eraser = { // 橡皮擦擦除
      color: 'transparent',
      strokeColor: '#000000',
      penWidth: 15,
      lineWidth: 2,
      pointer: false
    },
    wiper = {
      pointer: './static/assets/img/eraser.cur',
      pointerWidth: 42,
      pointerHeight: 56,
      radius: 8
    }
  }) {
    document.querySelectorAll(className).forEach((element) => {
      if (element.editor) {
        element.editor.penStyle = { type }
        switch (type) {
          case 'pen':
            element.editor.theme = { ink }
            break
          case 'eraser':
            element.editor.theme = { eraser }
            break
          case 'wiper':
            const _wiper = {
              pointer: wiper.pointer,
              radius: 8
            }
            if (wiper.pointerWidth > 60 || wiper.pointerHeight > 76) { // 设置最大尺寸
              _wiper.pointerWidth = 60
              _wiper.pointerHeight = 76
            } else {
              _wiper.pointerWidth = wiper.pointerWidth
              _wiper.pointerHeight = wiper.pointerHeight
            }
            element.editor.theme = { eraser: Object.assign({}, eraser, _wiper) }
            break
        }
      }
    })
  },
  // 设置单个画布的绘制参数
  setPenStyleSingle ({
    className,
    type = 'pen', // select:选中状态 pen:钢笔 eraser:橡皮檫
    ink = {
      color: '#FF2121',
      penWidth: 0.2 * 3
    },
    eraser = { // 橡皮擦擦除
      color: 'transparent',
      strokeColor: '#000000',
      penWidth: 15,
      lineWidth: 2,
      pointer: false
    },
    wiper = {
      pointer: './static/assets/img/eraser.cur',
      width: 56,
      pointerWidth: 42,
      pointerHeight: 56,
      radius: 8
    }
  }) {
    const element = document.querySelector(className)
    if (element.editor) {
      element.editor.penStyle = { type }
      switch (type) {
        case 'pen':
          element.editor.theme = { ink }
          break
        case 'eraser':
          element.editor.theme = { eraser }
          break
        case 'wiper':
          element.editor.theme = { eraser: Object.assign({}, eraser, wiper) }
          break
      }
    }
  },
  // 获取绘制canvas的imageData
  getCoreImageData ({
    className,
    // containerName, // 盒子容器
    paperIndex,
    width,
    height
  }) {
    let data = []
    // document.querySelectorAll(containerName)[paperIndex].editor.forceUpdate() // 强制更新
    let ctx = document.querySelectorAll(className)[paperIndex].getContext('2d')
    data = ctx.getImageData(0, 0, width, height)
    return data
  }
}
